package Tests
{
	import Box2D.Collision.Shapes.b2EdgeShape;
	import Box2D.Collision.Shapes.b2PolygonShape;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.Joints.b2PrismaticJointDef;
	import Box2D.Dynamics.Joints.b2RevoluteJointDef;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2BodyType;
	import Box2D.Dynamics.b2FixtureDef;
	
	import Framework.Test;
	
	public class BodyTypes extends Test
	{
		private var m_attachment:b2Body;
		private var m_platform:b2Body;
		private var m_speed:Number;
		public function BodyTypes()
		{
			super();
			createGround()
			createAttachment()
			createPlatform()
			createPayload()
		}
		private function createGround():void{
			var shape:b2EdgeShape = new b2EdgeShape;
			shape.Set(new b2Vec2(-20,0),new b2Vec2(20,0));
			m_groundBody.CreateFixtureByShape(shape,0);
		}
		private function createAttachment():void{
			var bd:b2BodyDef = new b2BodyDef;
			bd.type = b2BodyType.b2_dynamicBody;
			bd.position.Set(0,3);
			m_attachment = m_world.CreateBody(bd);
			
			var shape:b2PolygonShape = new b2PolygonShape;
			shape.SetAsBox(.5,2);
			m_attachment.CreateFixtureByShape(shape,2);
		}
		private function createPlatform():void{
			var bd:b2BodyDef = new b2BodyDef;
			bd.type = b2BodyType.b2_dynamicBody;
			bd.position.Set(-4.0, 5.0);
			m_platform = m_world.CreateBody(bd);
			
			var shape:b2PolygonShape = new b2PolygonShape;
			shape.SetAsBoxByCenter(0.5, 4.0, new b2Vec2(4.0, 0.0), 0.5 * Math.PI);
			var fd:b2FixtureDef = new b2FixtureDef;
			fd.shape = shape;
			fd.friction = 0.6;
			fd.density = 2.0;
			m_platform.CreateFixture(fd);
			
			var rjd:b2RevoluteJointDef = new b2RevoluteJointDef;
			rjd.Initialize(m_attachment, m_platform, new b2Vec2(0.0, 5.0));
			rjd.maxMotorTorque = 50.0;
			rjd.enableMotor = true;
			m_world.CreateJoint(rjd);
			
			var pjd:b2PrismaticJointDef = new b2PrismaticJointDef;
			pjd.Initialize(m_groundBody, m_platform, new b2Vec2(0.0, 5.0),new b2Vec2(1.0, 0.0));
			
			pjd.maxMotorForce = 1000.0;
			pjd.enableMotor = true;
			pjd.lowerTranslation = -10.0;
			pjd.upperTranslation = 10.0;
			pjd.enableLimit = true;
			
			m_world.CreateJoint(pjd);

			m_speed = 3.0;			
		}
		private function createPayload():void{
			var bd:b2BodyDef = new b2BodyDef;
			bd.type = b2BodyType.b2_dynamicBody;
			bd.position.Set(0.0, 8.0);
			var body:b2Body = m_world.CreateBody(bd);
			
			var shape:b2PolygonShape = new b2PolygonShape;
			shape.SetAsBox(0.75, 0.75);
			
			var fd:b2FixtureDef = new b2FixtureDef;
			fd.shape = shape;
			fd.friction = 0.6;
			fd.density = 2.0;
			
			body.CreateFixture(fd);			
		}
		public override function Key(key:String):void
		{
			switch (key)
			{
				case 'd':
					m_platform.SetType(b2BodyType.b2_dynamicBody);
					break;
				
				case 's':
					m_platform.SetType(b2BodyType.b2_staticBody);
					break;
				
				case 'k':
					m_platform.SetType(b2BodyType.b2_kinematicBody);
					m_platform.SetLinearVelocity(new b2Vec2(-m_speed, 0.0));
					m_platform.SetAngularVelocity(0.0);
					break;
			}
		}
		public override function Step():void
		{
			// Drive the kinematic body.
			if (m_platform.GetType() == b2BodyType.b2_kinematicBody)
			{
				var p:b2Vec2 = m_platform.GetTransform().position;
				var v:b2Vec2 = m_platform.GetLinearVelocity();
				
				if ((p.x < -10.0 && v.x < 0.0) ||
					(p.x > 10.0 && v.x > 0.0))
				{
					v.x = -v.x;
					m_platform.SetLinearVelocity(v);
				}
			}
			super.Step();
		}
		public override function get hotKeyNote():String{return 'Keys: (d) dynamic, (s) static, (k) kinematic'}
	}
}